////////////////////////////////////////////////////////////////////////////////
// Filename: basicgame.cpp
////////////////////////////////////////////////////////////////////////////////
#include "basicgame.hpp"
#include "../graphics/polygon.hpp"
#include "../graphics/sprite.hpp"

BasicGame::BasicGame(LPCSTR applicationName) {
	m_gameObject = NULL;
	m_graphics = NULL;
	m_applicationName = applicationName;
}

BasicGame::~BasicGame() {

}

void BasicGame::Run() {
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG));
	bool result;

	result = InitLoop();
	if (!result) {
		ShutdownLoop();
		return;
	}

	while (msg.message != WM_QUIT) {
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		Update(m_gameObject, m_graphics);

		m_graphics->BeginScene(0.0f, 0.0f, 0.0f, 1.0f);

		m_graphics->GetCamera()->Render();

		Render(m_gameObject, m_graphics);

		while (m_graphics->m_renderQueue->size() > 0) {
			m_graphics->m_renderQueue->front()->SetActive(m_graphics->GetDirect3D()->GetDeviceContext());
			if (dynamic_cast<miv::Polygon*>(m_graphics->m_renderQueue->front())) {
				m_graphics->GetShader()->Render(m_graphics->GetDirect3D()->GetDeviceContext(),
						m_graphics->m_renderQueue->front()->GetIndexCount(), *m_graphics->m_renderQueue->front()->GetModelMatrix(),
						*m_graphics->GetCamera()->GetViewMatrix(), *m_graphics->GetDirect3D()->GetOrthoMatrix());
			} else if (dynamic_cast<Sprite*>(m_graphics->m_renderQueue->front())) {
				if (dynamic_cast<Sprite*>(m_graphics->m_renderQueue->front())->IsAlphaEnabled()) {
					m_graphics->GetDirect3D()->TurnOnAlphaBlending();
				}
				m_graphics->GetTextureShader()->Render(m_graphics->GetDirect3D()->GetDeviceContext(),
						m_graphics->m_renderQueue->front()->GetIndexCount(), *m_graphics->m_renderQueue->front()->GetModelMatrix(),
						*m_graphics->GetCamera()->GetViewMatrix(), *m_graphics->GetDirect3D()->GetOrthoMatrix(),
						dynamic_cast<Sprite*>(m_graphics->m_renderQueue->front())->GetTexture());
				m_graphics->GetDirect3D()->TurnOffAlphaBlending();
			}
			m_graphics->m_renderQueue->pop();
		}

		m_graphics->EndScene();
	}

	ShutdownLoop();
}

void BasicGame::Initialize(GameObject* gameObject, Graphics* graphics) {

}

void BasicGame::Shutdown(GameObject* gameObject, Graphics* graphics) {

}

void BasicGame::Update(GameObject* gameObject, Graphics* graphics) {

}

void BasicGame::Render(GameObject* gameObject, Graphics* graphics) {

}

bool BasicGame::InitLoop() {
	bool result;

	m_gameObject = new GameObject(m_applicationName);
	if (!m_gameObject) {
		return false;
	}

	result = m_gameObject->Initialize();
	if (!result) {
		return false;
	}

	m_graphics = new Graphics();
	if (!m_graphics) {
		return false;
	}

	result = m_graphics->Initialize(m_gameObject->GetWidth(), m_gameObject->GetHeight(),
			m_gameObject->GetHandle());

	Initialize(m_gameObject, m_graphics);

	return true;
}

void BasicGame::ShutdownLoop() {
	Shutdown(m_gameObject, m_graphics);

	m_gameObject->Shutdown();
	delete m_gameObject;
	m_gameObject = NULL;
}
